/* Game.cpp
 * Project build start point (main)
 *
 * Last Modified: 08.12.2013
 * Author: Guilherme S.G.
 *
 * TODO:
 */

#include "Game.h"
#include "MenuView.h"
#include "SelectionView.h"
#include "VersusView.h"
#include "CalibrationView.h"
#include "InstructionsView.h"
#include "CreditsView.h"
//#include "Ninja.h"

Game *controller = nullptr;

int main(int argc, char *argv[])
{
    /* Initialize game components */
    controller = new Game(640, 480, ALLEGRO_WINDOWED | ALLEGRO_FRAMELESS | ALLEGRO_NOFRAME);
    
    /* Run the game */
    controller->mainLoop();
    
    delete controller;
    
    return EXIT_SUCCESS;
}

Game::Game(const int screenWidth_, const int screenHeight_, const int flags_)
{
    running = true;
    screenWidth = screenWidth_;
    screenHeight = screenHeight_;
    int error = 1;
    resources = new ResourceManager();
    
    /* Initialize Allegro5 components */
    error = al_init();
    error = al_init_primitives_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    error = al_init_image_addon();
    error = al_install_keyboard();
    al_install_audio();
    al_init_acodec_addon();
    
    if(error == 0)
    {
        std::cerr << "Could not initialize one of Allegro's components" << std::endl;
    }
    
    /* Create the game window */
    screen = al_create_display(screenWidth_, screenHeight_);
    al_set_new_display_flags(flags_);
    
    if(screen == nullptr)
    {
        std::cerr << "Could not initialized Allegro Display with options: " << screenWidth_ << " " << screenHeight_ << " " << flags_ <<std::endl;
    }
    
    eventQueue = al_create_event_queue();
    timer = al_create_timer(1.0 / FPS);
    
    al_register_event_source(eventQueue, al_get_keyboard_event_source());
    al_register_event_source(eventQueue, al_get_timer_event_source(timer));
    al_register_event_source(eventQueue, al_get_display_event_source(screen));
    
    redraw = true;
    currentView = nullptr;
    currentScreen = nextScreen = MENU;
    previousScreen = END;
    
    /* Create the window for the webcam video */
    //video = new VideoCapture(screenWidth_, screenHeight_);
    
    /* Already create and store only once each HandSeal possible */
    /*handSeals.insert(std::pair<std::string,HandSeal*>("Boar",new HsBoar()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Dog",new HsDog()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Dragon",new HsDragon()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Horse",new HsHorse()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Monkey",new HsMonkey()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Ox",new HsOx()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Rabbit",new HsRabbit()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Ram",new HsRam()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Rat",new HsRat()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Rooster",new HsRooster()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Snake",new HsSnake()));
    handSeals.insert(std::pair<std::string,HandSeal*>("Tiger",new HsTiger()));
    
    currentSeal = nullptr;*/
    
    srand((unsigned)time(nullptr));

}

Game::~Game()
{
    al_destroy_display(screen);
    al_destroy_event_queue(eventQueue);
    al_destroy_timer(timer);
    
    //delete video;
    delete resources;
    
    for(int i = 0; i < ninjas.size(); i++)
        delete ninjas[i];
}

void Game::mainLoop()
{
    currentView = new MenuView();
    
    al_start_timer(timer);
    
    while(running)
    {
        //Video Window
        
        // Game Window
        ALLEGRO_EVENT event;
        al_wait_for_event(eventQueue, &event);
        
        currentView->handleEvents(&event);
        
        if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
        {
            running = false;
        }
        else if(event.type == ALLEGRO_EVENT_TIMER)
        {
            redraw = true;
            
            currentView->update();
        }
        
        if(redraw)
        {
            redraw = false;
            
            al_clear_to_color(al_map_rgb(0, 0, 0));
            
            currentView->render();
            
            al_flip_display();
        }
        
        //Execute transition between Views if necessary
        if(currentScreen != nextScreen)
        {
            delete currentView;
            currentView = nullptr;
            
            switch(nextScreen)
            {
                case END:
                    running = false;
                    break;
                    
                case MENU:
                    currentView = new MenuView();
                    break;
                 
                case SELECTION:
                    currentView = new SelectionView();
                    break;
                    
                case VERSUS:
                    currentView = new VersusView();
                    break;
                    
                case CALIBRATION:
                    currentView = new CalibrationView();
                    break;
                    
                case INSTRUCTIONS:
                    currentView = new InstructionsView();
                    break;
                    
                case CREDITS:
                    currentView = new CreditsView();
                    break;
                    
                default:
                    break;
            }
            
            previousScreen = currentScreen;
            currentScreen = nextScreen;
        }
    }
    
    if(currentView != nullptr)
        delete currentView;
}